﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Narwhunderful.Aphelia.Framework.Graphics;
using Narwhunderful.Aphelia.Framework.Input.Keyboard;

namespace Narwhunderful.Aphelia.Framework.UI
{

    public abstract class UIBaseComponent : SpriteComponent, IBaseUIComponent
    {

        public event EventHandler<EventArgs> DesigningChanged = null;

        public event EventHandler<KeyEventArgs> KeyDown = null;
        public event EventHandler<KeyEventArgs> KeyPress = null;
        public event EventHandler<KeyEventArgs> KeyUp = null;

        UIManager _manager = null;
        public virtual UIManager UIManager
        {
            get
            {
                return _manager;
            }
        }

        bool _isDesigning = true;
        public virtual bool IsDesigning
        {
            get
            {
                return _isDesigning;
            }
            internal set
            {
                _isDesigning = value;
            }
        }

        Vector2 _actualLocation = Vector2.Zero;
        public virtual Vector2 ActualLocation
        {
            get
            {
                return _actualLocation;
            }
            protected set
            {
                _actualLocation = value;
            }
        }

        public override Vector2 Location
        {
            get
            {
                return base.Location;
            }
            set
            {
                base.Location = value;
                base.NeedsUpdate = true;
            }
        }

        Rectangle _scissorRectangle = Rectangle.Empty;
        public Rectangle ScissorRectangle
        {
            get
            {
                return _scissorRectangle;
            }
            protected set
            {
                _scissorRectangle = value;
            }
        }

        public UIBaseComponent(UIManager manager)
            : base(manager.Game, manager.DrawingContext2D)
        {
            _manager = manager;
            base.SpriteBatch = new SpriteBatch(base.Game.GraphicsDevice);
        }

        public override bool CanUpdate(GameTime gameTime)
        {
            if (_isDesigning) return false;
            return base.CanUpdate(gameTime);
        }

        public override bool CanDraw()
        {
            if (_isDesigning) return false;
            return base.CanDraw();
        }

        protected override void BeginDraw()
        {
            base.BeginDraw();
            base.Game.GraphicsDevice.ScissorRectangle = _scissorRectangle;
            BeginSpriteBatch();
        }

        protected virtual void BeginSpriteBatch()
        {
            base.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, _manager.RasterizerState, null);
        }

        protected override void InternalDraw()
        {
            base.InternalDraw();
        }

        protected override void EndDraw()
        {
            EndSpriteBatch();
            base.Game.GraphicsDevice.ScissorRectangle = base.Game.GraphicsDevice.PresentationParameters.Bounds;
            base.EndDraw();
        }

        protected virtual void EndSpriteBatch()
        {
            base.SpriteBatch.End();
        }

        public virtual void BeginDesigning()
        {
            if (!_isDesigning)
            {
                _isDesigning = true;
                OnDesigningChanged(this, new EventArgs());
            }
        }

        public virtual void EndDesigning()
        {
            if (_isDesigning)
            {
                _isDesigning = false;
                base.NeedsUpdate = true;
                OnDesigningChanged(this, new EventArgs());
            }
        }

        protected override void UpdateRenderLocation()
        {
            base.UpdateRenderLocation();
            UpdateActualLocation();
        }

        protected virtual void UpdateActualLocation()
        {
            _actualLocation = base.Location;
        }

        protected override void InternalUpdate(GameTime gameTime)
        {
            base.InternalUpdate(gameTime);
            UpdateScissor();
        }

        protected virtual void UpdateScissor()
        {
            _scissorRectangle = Graphics.DrawingContext2D.RectangleIntersect(base.Bounds, base.Game.GraphicsDevice.Viewport.Bounds);
        }

        public virtual void Show()
        {
            base.IsVisible = true;
        }

        public virtual void Hide()
        {
            base.IsVisible = false;
        }

        protected internal virtual void OnDesigningChanged(object sender, EventArgs e)
        {
            if (DesigningChanged != null) DesigningChanged(sender, e);
        }

        protected internal virtual void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (KeyDown != null) KeyUp(sender, e);
        }

        protected internal virtual void OnKeyPress(object sender, KeyEventArgs e)
        {
            if (KeyPress != null) KeyPress(sender, e);
        }

        protected internal virtual void OnKeyUp(object sender, KeyEventArgs e)
        {
            if (KeyUp != null) KeyUp(sender, e);
        }

    }

}
